﻿using Castle.MicroKernel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WJP.Dependency
{
    /// <summary>
    /// 为类定义接口，用来解析依赖
    /// </summary>
    public interface IIocResolver
    {
        /// <summary>
        /// 从IOC容器获取一个对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="service"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        object Resolve(string key, Type service, Arguments arguments);

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        T Resolve<T>(string key, Arguments arguments);

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arguments"></param>
        /// <returns></returns>
        T Resolve<T>(Arguments arguments);

        /// <summary>
        /// 从IOC容器获取一个对象
        /// <para>返回对象必须在使用后释放，请看<see cref="Release(object)"/></para>
        /// </summary>
        /// <typeparam name="T">要得到的对象的类型</typeparam>
        /// <returns>对象实例</returns>
        T Resolve<T>();

        /// <summary>
        /// 从IOC容器获取一个对象
        /// <para>返回对象必须在使用后释放，请看<see cref="Release(object)"/></para>
        /// </summary>
        /// <param name="type">要得到的对象的类型</param>
        /// <returns>对象实例</returns>
        object Resolve(Type type);

        /// <summary>
        /// 从IOC容器获取一个对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        object Resolve(string key, Type service);

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        T Resolve<T>(string key);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="service"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        object Resolve(Type service, Arguments arguments);

        /// <summary>
        /// 获取给定类型的所有实现
        /// <para>返回对象必须在使用后释放，请看<see cref="Release(object)"/></para>
        /// </summary>
        /// <typeparam name="T">要解析的对象类型</typeparam>
        /// <returns>对象实例</returns>
        T[] ResolveAll<T>();

        /// <summary>
        /// 获取给定类型的所有实现
        /// <para>返回对象必须在使用后释放，请看<see cref="Release(object)"/></para>
        /// </summary>
        /// <param name="type">要解析的对象类型</param>
        /// <returns>对象实例</returns>
        Array ResolveAll(Type type);

        /// <summary>
        /// 获取给定类型的所有实现
        /// </summary>
        /// <param name="service"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        Array ResolveAll(Type service, Arguments arguments);

        /// <summary>
        /// 获取给定类型的所有实现
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arguments"></param>
        /// <returns></returns>
        T[] ResolveAll<T>(Arguments arguments);

        /// <summary>
        /// 释放一个解析依赖对象。
        /// </summary>
        /// <param name="obj">要释放的对象</param>
        void Release(object obj);

        /// <summary>
        /// 检查给定类型是否已注册
        /// </summary>
        /// <param name="type">要检查的类型</param>
        /// <returns></returns>
        bool IsRegistered(Type type);

        /// <summary>
        /// 检查给定类型是否已注册
        /// </summary>
        /// <typeparam name="T">要检查的类型</typeparam>
        /// <returns></returns>
        bool IsRegistered<T>();
    }
}
